use strict;


=head1 NAME

  RTx::AssetTracker::Groups -- Class Description
 
=head1 SYNOPSIS

  use RTx::AssetTracker::Groups

=head1 DESCRIPTION


=head1 METHODS

=cut

package RTx::AssetTracker::Groups;

use vars qw( @ISA );
@ISA= qw(RT::Groups);

# {{{ LimitToRolesForType

=item LimitToRolesForType TYPE_ID

Limits the set of groups found to role groups for type TYPE_ID

=cut

sub LimitToRolesForType {
    my $self = shift;
    my $type = shift;
    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RTx::AssetTracker::Type-Role');
    $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $type);
}

# }}}

sub WithATRight {
    my $self = shift;
    my %args = ( Right                  => undef,
                 Object =>              => undef,
                 IncludeSystemRights    => 1,
                 IncludeSuperusers      => undef,
                 @_ );

    my $acl        = $self->NewAlias('ACL');

    # {{{ Find only rows where the right granted is the one we're looking up or _possibly_ superuser
    $self->Limit( ALIAS           => $acl,
                  FIELD           => 'RightName',
                  OPERATOR        => ($args{Right} ? '=' : 'IS NOT'),
                  VALUE           => $args{Right} || 'NULL',
                  ENTRYAGGREGATOR => 'OR' );

    if ( $args{'IncludeSuperusers'} and $args{'Right'} ) {
        $self->Limit( ALIAS           => $acl,
                      FIELD           => 'RightName',
                      OPERATOR        => '=',
                      VALUE           => 'SuperUser',
                      ENTRYAGGREGATOR => 'OR' );
    }
    # }}}

    my ($or_check_asset_roles, $or_check_roles);
    my $which_object = "$acl.ObjectType = 'RTx::AssetTracker::System'";

    if ( defined $args{'Object'} ) {
        if ( ref($args{'Object'}) eq 'RTx::AssetTracker::Asset' ) {
            $or_check_asset_roles =
                " OR ( main.Domain = 'RTx::AssetTracker::Asset-Role' AND main.Instance = " . $args{'Object'}->Id . ") ";

            # If we're looking at asset rights, we also want to look at the associated queue rights.
            # this is a little bit hacky, but basically, now that we've done the asset roles magic,
            # we load the queue object and ask all the rest of our questions about the queue.
            $args{'Object'}   = $args{'Object'}->TypeObj;
        }
        # TODO XXX This really wants some refactoring
        if ( ref($args{'Object'}) eq 'RTx::AssetTracker::Type' ) {
            $or_check_roles =
                " OR ( ( (main.Domain = 'RTx::AssetTracker::Type-Role' AND main.Instance = " .
                $args{'Object'}->Id . ") $or_check_asset_roles ) " .
                " AND main.Type = $acl.PrincipalType) ";
        }

        if ( $args{'IncludeSystemRights'} ) {
            $which_object .= ' OR ';
        }
        else {
            $which_object = '';
        }
        $which_object .=
            " ($acl.ObjectType = '" . ref($args{'Object'}) . "'" .
            " AND $acl.ObjectId = " . $args{'Object'}->Id . ") ";
    }

    $self->_AddSubClause( "WhichObject", "($which_object)" );

    $self->_AddSubClause( "WhichGroup",
        qq{
          ( (    $acl.PrincipalId = main.id
             AND $acl.PrincipalType = 'Group'
             AND (   main.Domain = 'SystemInternal'
                  OR main.Domain = 'UserDefined'
                  OR main.Domain = 'ACLEquivalence'))
           $or_check_roles)
        }
    );
}

# {{{ LimitToRolesForSystem

=item LimitToRolesForSystem System_ID

Limits the set of groups found to role groups for System System_ID

=cut

sub LimitToRolesForSystem {
    my $self = shift;
    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'RTx::AssetTracker::System-Role');
}

# }}}

=head2 NewItem

Returns an empty new RTx::AssetTracker::Group item

=cut

sub NewItem {
    my $self = shift;
    return(RTx::AssetTracker::Group->new($self->CurrentUser));
}


1;
